package cn.dansj.common.utils.json;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.PropertyName;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

class GsonAnnotationIntrospector extends JacksonAnnotationIntrospector {
    @Override
    public PropertyName findNameForSerialization(Annotated a) {
        // 优先处理@SerializedName
        SerializedName serializedName = a.getAnnotation(SerializedName.class);
        if (serializedName != null) return new PropertyName(serializedName.value());
        // 然后处理@Expose
        Expose expose = a.getAnnotation(Expose.class);
        if (expose != null && !expose.serialize()) return PropertyName.NO_NAME; // 相当于排除
        return super.findNameForSerialization(a);
    }

    @Override
    public PropertyName findNameForDeserialization(Annotated a) {
        // 反序列化时处理@SerializedName
        SerializedName serializedName = a.getAnnotation(SerializedName.class);
        if (serializedName != null) return new PropertyName(serializedName.value());
        // 处理@Expose
        Expose expose = a.getAnnotation(Expose.class);
        if (expose != null && !expose.deserialize()) return PropertyName.NO_NAME; // 相当于排除
        return super.findNameForDeserialization(a);
    }

    @Override
    public boolean hasIgnoreMarker(AnnotatedMember m) {
        Expose expose = m.getAnnotation(Expose.class);
        if (expose != null && !expose.serialize()) return true;
        return super.hasIgnoreMarker(m);
    }

    @Override
    public JsonProperty.Access findPropertyAccess(Annotated m) {
        Expose expose = m.getAnnotation(Expose.class);
        if (expose != null) {
            if (expose.deserialize() && !expose.serialize()) {
                return JsonProperty.Access.WRITE_ONLY;
            } else if (!expose.deserialize() && expose.serialize()) {
                return JsonProperty.Access.READ_ONLY;
            }
        }
        return super.findPropertyAccess(m);
    }
}
